{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "04eb2284",
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from tensorflow.keras.layers import Dropout, Dense, SimpleRNN\n",
    "import matplotlib.pyplot as plt\n",
    "import os\n",
    "import pandas as pd\n",
    "from sklearn.preprocessing import MinMaxScaler\n",
    "from sklearn.metrics import mean_squared_error, mean_absolute_error\n",
    "import math"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "d3a06b0f",
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "numpy 1.21.4\n",
      "pandas 1.3.4\n",
      "tensorflow 2.7.0\n"
     ]
    }
   ],
   "source": [
    "for module in np, pd, tf:\n",
    "     print (module.__name__, module.__version__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "8d798630",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 这两行代码解决 plt 中文显示的问题\n",
    "plt.rcParams['font.sans-serif'] = ['SimHei']\n",
    "plt.rcParams['axes.unicode_minus'] = False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "ea365654",
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "stock = pd.read_csv('../dataset/600031.csv')  # 读取股票文件"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "381a64a4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>日期</th>\n",
       "      <th>开盘</th>\n",
       "      <th>收盘</th>\n",
       "      <th>最高</th>\n",
       "      <th>最低</th>\n",
       "      <th>成交量</th>\n",
       "      <th>成交额</th>\n",
       "      <th>振幅</th>\n",
       "      <th>涨跌幅</th>\n",
       "      <th>涨跌额</th>\n",
       "      <th>换手率</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>2020-11-09</td>\n",
       "      <td>27.80</td>\n",
       "      <td>27.54</td>\n",
       "      <td>28.14</td>\n",
       "      <td>26.89</td>\n",
       "      <td>856249</td>\n",
       "      <td>2348800992</td>\n",
       "      <td>4.55</td>\n",
       "      <td>0.18</td>\n",
       "      <td>0.05</td>\n",
       "      <td>1.01</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2020-11-10</td>\n",
       "      <td>27.98</td>\n",
       "      <td>27.32</td>\n",
       "      <td>27.98</td>\n",
       "      <td>26.91</td>\n",
       "      <td>558824</td>\n",
       "      <td>1523209504</td>\n",
       "      <td>3.89</td>\n",
       "      <td>-0.80</td>\n",
       "      <td>-0.22</td>\n",
       "      <td>0.66</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2020-11-11</td>\n",
       "      <td>27.33</td>\n",
       "      <td>28.31</td>\n",
       "      <td>28.86</td>\n",
       "      <td>27.21</td>\n",
       "      <td>1015374</td>\n",
       "      <td>2873205488</td>\n",
       "      <td>6.04</td>\n",
       "      <td>3.62</td>\n",
       "      <td>0.99</td>\n",
       "      <td>1.20</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>2020-11-12</td>\n",
       "      <td>28.31</td>\n",
       "      <td>28.70</td>\n",
       "      <td>28.88</td>\n",
       "      <td>27.91</td>\n",
       "      <td>718595</td>\n",
       "      <td>2041558432</td>\n",
       "      <td>3.43</td>\n",
       "      <td>1.38</td>\n",
       "      <td>0.39</td>\n",
       "      <td>0.85</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>2020-11-13</td>\n",
       "      <td>28.28</td>\n",
       "      <td>28.16</td>\n",
       "      <td>28.50</td>\n",
       "      <td>27.60</td>\n",
       "      <td>674807</td>\n",
       "      <td>1888773520</td>\n",
       "      <td>3.14</td>\n",
       "      <td>-1.88</td>\n",
       "      <td>-0.54</td>\n",
       "      <td>0.80</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "           日期     开盘     收盘     最高     最低      成交量         成交额    振幅   涨跌幅  \\\n",
       "0  2020-11-09  27.80  27.54  28.14  26.89   856249  2348800992  4.55  0.18   \n",
       "1  2020-11-10  27.98  27.32  27.98  26.91   558824  1523209504  3.89 -0.80   \n",
       "2  2020-11-11  27.33  28.31  28.86  27.21  1015374  2873205488  6.04  3.62   \n",
       "3  2020-11-12  28.31  28.70  28.88  27.91   718595  2041558432  3.43  1.38   \n",
       "4  2020-11-13  28.28  28.16  28.50  27.60   674807  1888773520  3.14 -1.88   \n",
       "\n",
       "    涨跌额   换手率  \n",
       "0  0.05  1.01  \n",
       "1 -0.22  0.66  \n",
       "2  0.99  1.20  \n",
       "3  0.39  0.85  \n",
       "4 -0.54  0.80  "
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stock.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f9e11616",
   "metadata": {},
   "source": [
    "### 用收盘价预测股价\n",
    "### 将数据集分成训练集：测试集 == 4:1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "b34a5c82",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 取收盘价特征\n",
    "training_set = stock.iloc[0:int(len(stock) / 5 * 4), 2:3].values\n",
    "test_set = stock.iloc[int(len(stock) / 5 * 4):, 2:3].values"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "640134f4",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((201, 1), (51, 1))"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "training_set.shape , test_set.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1437e872",
   "metadata": {},
   "source": [
    "# 归一化处理（进行缩放）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "cd9d2883",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 归一化\n",
    "sc = MinMaxScaler(feature_range=(0, 1))  # 定义归一化：归一化到(0，1)之间\n",
    "# 缩放\n",
    "training_set_scaled = sc.fit_transform(training_set)  # 求得训练集的最大值，最小值这些训练集固有的属性，并在训练集上进行归一化\n",
    "test_set = sc.transform(test_set)  # 利用训练集的属性对测试集进行归一化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "bf700d1f",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 数据参数：\n",
    "# 序列长度\n",
    "seq_len = 5"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9005792e",
   "metadata": {},
   "source": [
    "# 训练集处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "16df04c4",
   "metadata": {},
   "outputs": [],
   "source": [
    "x_train = []\n",
    "y_train = []\n",
    "# 数据进行分组\n",
    "for i in range(5, len(training_set_scaled)):\n",
    "    x_train.append(training_set_scaled[i - seq_len:i, 0])\n",
    "    y_train.append(training_set_scaled[i, 0])\n",
    "\n",
    "# 对训练集进行打乱\n",
    "np.random.seed(7)\n",
    "np.random.shuffle(x_train)\n",
    "np.random.seed(7)\n",
    "np.random.shuffle(y_train)\n",
    "tf.random.set_seed(7)\n",
    "\n",
    "# 将训练集由list格式变为array格式\n",
    "x_train, y_train = np.array(x_train), np.array(y_train)\n",
    "x_train = np.reshape(x_train, (x_train.shape[0], seq_len, 1))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d60e7ecc",
   "metadata": {},
   "source": [
    "# 测试集处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "b9e187ff",
   "metadata": {},
   "outputs": [],
   "source": [
    "x_test = []\n",
    "y_test = []\n",
    "\n",
    "# 利用for循环，遍历整个测试集，提取测试集中连续5(seq_len)天的开盘价作为输入特征x_train，第6(seq_len+1)天的数据作为标签\n",
    "for i in range(seq_len, len(test_set)):\n",
    "    x_test.append(test_set[i - seq_len:i, 0])\n",
    "    y_test.append(test_set[i, 0])\n",
    "\n",
    "# 测试集变array并reshape为符合RNN输入要求：[送入样本数， 循环核时间展开步数， 每个时间步输入特征个数]\n",
    "x_test, y_test = np.array(x_test), np.array(y_test)\n",
    "x_test = np.reshape(x_test, (x_test.shape[0], seq_len, 1))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7bfede67",
   "metadata": {},
   "source": [
    "# 构建模型\n",
    "\n",
    "### 序列化建模，一般步骤为：\n",
    "\n",
    "　　* 1、实例化一个Sequential类，该类是继承于Model类；\n",
    "\n",
    "　　* 2、添加所需要的神经网络层；\n",
    "\n",
    "　　* 3、用compile进行编译模型；\n",
    "\n",
    "　　* 4、用fit训练模型；\n",
    "\n",
    "　　* 5、用predict预测。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "915a6f87",
   "metadata": {},
   "outputs": [],
   "source": [
    "model = tf.keras.Sequential([\n",
    "    SimpleRNN(80, return_sequences=True),\n",
    "    Dropout(0.2),\n",
    "    SimpleRNN(100),\n",
    "    Dropout(0.2),\n",
    "    Dense(1)\n",
    "])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "13e2a40d",
   "metadata": {},
   "outputs": [],
   "source": [
    "model.compile(optimizer=tf.keras.optimizers.Adam(0.001),loss='mean_squared_error')  \n",
    "# 损失函数用均方误差\n",
    "# 该应用只观测loss数值，不观测准确率，所以删去metrics选项，一会在每个epoch迭代显示时只显示loss值"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4feb7c32",
   "metadata": {},
   "source": [
    "# 预测一次，并保存预测结构，用于之后的验证"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "d6ee0eca",
   "metadata": {},
   "outputs": [],
   "source": [
    "checkpoint_save_path = \"./checkpoint/rnn_stock.ckpt\"\n",
    "if os.path.exists(checkpoint_save_path + '.index'):\n",
    "    print('-------------load the model-----------------')\n",
    "    model.load_weights(checkpoint_save_path)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9af12663",
   "metadata": {},
   "source": [
    "# 参数详解：\n",
    "* x=None, #输入的x值\n",
    "* y=None, #输入的y标签值\n",
    "* batch_size=None, #整数 ，每次梯度更新的样本数即批量大小。未指定，默认为32。\n",
    "* epochs=1, #迭代次数\n",
    "* verbose=1, #整数，代表以什么形式来展示日志状态，\n",
    "* verbose = 0 为不在标准输出流输出日志信息，verbose = 1 为输出进度条记录，verbose = 2 为每个epoch输出一行记录\n",
    "* callbacks=None, #回调函数，这个list中的回调函数将会在训练过程中的适当时机被调用，参考回调函数\n",
    "* validation_split=0.0, #浮点数0-1之间，用作验证集的训练数据的比例。模型将分出一部分不会被训练的验证数据，并将在每一轮结束时评估这些验证数据的误差和任何其他模型指标。\n",
    "* validation_data=None, #这个参数会覆盖 validation_split\n",
    "   即两个函数只能存在一个，它的输入为元组 (x_val，y_val)，这作为验证数据。\n",
    "* shuffle=True, #布尔值。是否在每轮迭代之前混洗数据\n",
    "* class_weight=None,\n",
    "* sample_weight=None, \n",
    "* initial_epoch=0, \n",
    "* steps_per_epoch=None, #一个epoch包含的步数（每一步是一个batch的数据送入）\n",
    "   当使用如TensorFlow数据Tensor之类的输入张量进行训练时，默认的None代表自动分割，即数据集样本数/batch样本数。\n",
    "* validation_steps=None, #在验证集上的step总数，仅当steps_per_epoch被指定时有用。\n",
    "* validation_freq=1, #指使用验证集实施验证的频率。当等于1时代表每个epoch结束都验证一次\n",
    "* max_queue_size=10,\n",
    "* workers=1,\n",
    "* use_multiprocessing=False   "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "195133aa",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 训练参数\n",
    "batch_size = 64\n",
    "epochs = 100\n",
    "validation_freq=1\n",
    "# 等等"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "d9e2df5b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/100\n",
      "4/4 [==============================] - 3s 169ms/step - loss: 0.2429 - val_loss: 0.0060\n",
      "Epoch 2/100\n",
      "4/4 [==============================] - 0s 38ms/step - loss: 0.0911 - val_loss: 0.0037\n",
      "Epoch 3/100\n",
      "4/4 [==============================] - 0s 35ms/step - loss: 0.0945 - val_loss: 0.0026\n",
      "Epoch 4/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0657 - val_loss: 0.0033\n",
      "Epoch 5/100\n",
      "4/4 [==============================] - 0s 38ms/step - loss: 0.0356 - val_loss: 8.4382e-04\n",
      "Epoch 6/100\n",
      "4/4 [==============================] - 0s 23ms/step - loss: 0.0434 - val_loss: 0.0011\n",
      "Epoch 7/100\n",
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0364 - val_loss: 0.0011\n",
      "Epoch 8/100\n",
      "4/4 [==============================] - 0s 23ms/step - loss: 0.0243 - val_loss: 0.0028\n",
      "Epoch 9/100\n",
      "4/4 [==============================] - 0s 21ms/step - loss: 0.0289 - val_loss: 9.7373e-04\n",
      "Epoch 10/100\n",
      "4/4 [==============================] - 0s 33ms/step - loss: 0.0259 - val_loss: 4.8274e-04\n",
      "Epoch 11/100\n",
      "4/4 [==============================] - 0s 23ms/step - loss: 0.0263 - val_loss: 7.7576e-04\n",
      "Epoch 12/100\n",
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0177 - val_loss: 0.0012\n",
      "Epoch 13/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0195 - val_loss: 0.0010\n",
      "Epoch 14/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0186 - val_loss: 7.7202e-04\n",
      "Epoch 15/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0155 - val_loss: 8.3404e-04\n",
      "Epoch 16/100\n",
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0132 - val_loss: 5.3009e-04\n",
      "Epoch 17/100\n",
      "4/4 [==============================] - 0s 38ms/step - loss: 0.0198 - val_loss: 4.4177e-04\n",
      "Epoch 18/100\n",
      "4/4 [==============================] - 0s 21ms/step - loss: 0.0137 - val_loss: 9.0208e-04\n",
      "Epoch 19/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0190 - val_loss: 9.7969e-04\n",
      "Epoch 20/100\n",
      "4/4 [==============================] - 0s 49ms/step - loss: 0.0159 - val_loss: 4.0420e-04\n",
      "Epoch 21/100\n",
      "4/4 [==============================] - 0s 24ms/step - loss: 0.0189 - val_loss: 4.1901e-04\n",
      "Epoch 22/100\n",
      "4/4 [==============================] - 0s 23ms/step - loss: 0.0114 - val_loss: 7.2895e-04\n",
      "Epoch 23/100\n",
      "4/4 [==============================] - 0s 21ms/step - loss: 0.0129 - val_loss: 6.3282e-04\n",
      "Epoch 24/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0160 - val_loss: 5.1285e-04\n",
      "Epoch 25/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0116 - val_loss: 8.2496e-04\n",
      "Epoch 26/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0127 - val_loss: 8.6082e-04\n",
      "Epoch 27/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0150 - val_loss: 8.4474e-04\n",
      "Epoch 28/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0132 - val_loss: 8.9285e-04\n",
      "Epoch 29/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0159 - val_loss: 4.9346e-04\n",
      "Epoch 30/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0113 - val_loss: 6.1734e-04\n",
      "Epoch 31/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0119 - val_loss: 5.6048e-04\n",
      "Epoch 32/100\n",
      "4/4 [==============================] - 0s 21ms/step - loss: 0.0098 - val_loss: 0.0011\n",
      "Epoch 33/100\n",
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0103 - val_loss: 0.0014\n",
      "Epoch 34/100\n",
      "4/4 [==============================] - 0s 21ms/step - loss: 0.0097 - val_loss: 7.7410e-04\n",
      "Epoch 35/100\n",
      "4/4 [==============================] - 0s 21ms/step - loss: 0.0082 - val_loss: 5.4235e-04\n",
      "Epoch 36/100\n",
      "4/4 [==============================] - 0s 23ms/step - loss: 0.0087 - val_loss: 5.6312e-04\n",
      "Epoch 37/100\n",
      "4/4 [==============================] - 0s 24ms/step - loss: 0.0115 - val_loss: 6.1904e-04\n",
      "Epoch 38/100\n",
      "4/4 [==============================] - 0s 25ms/step - loss: 0.0098 - val_loss: 4.0739e-04\n",
      "Epoch 39/100\n",
      "4/4 [==============================] - 0s 36ms/step - loss: 0.0119 - val_loss: 3.3746e-04\n",
      "Epoch 40/100\n",
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0113 - val_loss: 6.4401e-04\n",
      "Epoch 41/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0117 - val_loss: 4.9684e-04\n",
      "Epoch 42/100\n",
      "4/4 [==============================] - 0s 23ms/step - loss: 0.0093 - val_loss: 3.6217e-04\n",
      "Epoch 43/100\n",
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0100 - val_loss: 4.3505e-04\n",
      "Epoch 44/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0090 - val_loss: 4.4532e-04\n",
      "Epoch 45/100\n",
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0058 - val_loss: 3.9813e-04\n",
      "Epoch 46/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0082 - val_loss: 3.8287e-04\n",
      "Epoch 47/100\n",
      "4/4 [==============================] - 0s 21ms/step - loss: 0.0076 - val_loss: 6.3578e-04\n",
      "Epoch 48/100\n",
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0086 - val_loss: 6.4748e-04\n",
      "Epoch 49/100\n",
      "4/4 [==============================] - 0s 21ms/step - loss: 0.0076 - val_loss: 4.8956e-04\n",
      "Epoch 50/100\n",
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0140 - val_loss: 5.8739e-04\n",
      "Epoch 51/100\n",
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0071 - val_loss: 8.9354e-04\n",
      "Epoch 52/100\n",
      "4/4 [==============================] - 0s 37ms/step - loss: 0.0097 - val_loss: 3.0322e-04\n",
      "Epoch 53/100\n",
      "4/4 [==============================] - 0s 24ms/step - loss: 0.0105 - val_loss: 3.4391e-04\n",
      "Epoch 54/100\n",
      "4/4 [==============================] - 0s 21ms/step - loss: 0.0082 - val_loss: 5.9315e-04\n",
      "Epoch 55/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0114 - val_loss: 8.3874e-04\n",
      "Epoch 56/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0079 - val_loss: 4.4806e-04\n",
      "Epoch 57/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0079 - val_loss: 3.3104e-04\n",
      "Epoch 58/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0095 - val_loss: 7.1491e-04\n",
      "Epoch 59/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0102 - val_loss: 0.0011\n",
      "Epoch 60/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0132 - val_loss: 3.1410e-04\n",
      "Epoch 61/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0102 - val_loss: 3.5120e-04\n",
      "Epoch 62/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0105 - val_loss: 5.3359e-04\n",
      "Epoch 63/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0079 - val_loss: 3.0763e-04\n",
      "Epoch 64/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0097 - val_loss: 3.4589e-04\n",
      "Epoch 65/100\n",
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0071 - val_loss: 6.9592e-04\n",
      "Epoch 66/100\n",
      "4/4 [==============================] - 0s 23ms/step - loss: 0.0079 - val_loss: 5.1331e-04\n",
      "Epoch 67/100\n",
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0068 - val_loss: 4.1864e-04\n",
      "Epoch 68/100\n",
      "4/4 [==============================] - 0s 23ms/step - loss: 0.0070 - val_loss: 5.7700e-04\n",
      "Epoch 69/100\n",
      "4/4 [==============================] - 0s 23ms/step - loss: 0.0056 - val_loss: 7.7486e-04\n",
      "Epoch 70/100\n",
      "4/4 [==============================] - 0s 18ms/step - loss: 0.0054 - val_loss: 6.0464e-04\n",
      "Epoch 71/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0054 - val_loss: 5.6700e-04\n",
      "Epoch 72/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0098 - val_loss: 4.6612e-04\n",
      "Epoch 73/100\n",
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0052 - val_loss: 4.2260e-04\n",
      "Epoch 74/100\n",
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0065 - val_loss: 3.5719e-04\n",
      "Epoch 75/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0054 - val_loss: 3.4986e-04\n",
      "Epoch 76/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0062 - val_loss: 3.5256e-04\n",
      "Epoch 77/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0055 - val_loss: 3.1025e-04\n",
      "Epoch 78/100\n",
      "4/4 [==============================] - 0s 35ms/step - loss: 0.0082 - val_loss: 3.0069e-04\n",
      "Epoch 79/100\n",
      "4/4 [==============================] - 0s 21ms/step - loss: 0.0058 - val_loss: 6.8392e-04\n",
      "Epoch 80/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0082 - val_loss: 4.3097e-04\n",
      "Epoch 81/100\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0070 - val_loss: 3.5592e-04\n",
      "Epoch 82/100\n",
      "4/4 [==============================] - 0s 22ms/step - loss: 0.0066 - val_loss: 3.2267e-04\n",
      "Epoch 83/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0059 - val_loss: 3.8770e-04\n",
      "Epoch 84/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0049 - val_loss: 7.7375e-04\n",
      "Epoch 85/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0060 - val_loss: 6.7514e-04\n",
      "Epoch 86/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0072 - val_loss: 7.2318e-04\n",
      "Epoch 87/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0064 - val_loss: 8.5082e-04\n",
      "Epoch 88/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0063 - val_loss: 7.4415e-04\n",
      "Epoch 89/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0047 - val_loss: 5.0000e-04\n",
      "Epoch 90/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0070 - val_loss: 5.5137e-04\n",
      "Epoch 91/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0047 - val_loss: 8.0945e-04\n",
      "Epoch 92/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0073 - val_loss: 4.2072e-04\n",
      "Epoch 93/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0063 - val_loss: 3.8122e-04\n",
      "Epoch 94/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0089 - val_loss: 6.4329e-04\n",
      "Epoch 95/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0070 - val_loss: 0.0013\n",
      "Epoch 96/100\n",
      "4/4 [==============================] - 0s 19ms/step - loss: 0.0075 - val_loss: 4.6048e-04\n",
      "Epoch 97/100\n",
      "4/4 [==============================] - 0s 23ms/step - loss: 0.0064 - val_loss: 3.8100e-04\n",
      "Epoch 98/100\n",
      "4/4 [==============================] - 0s 20ms/step - loss: 0.0076 - val_loss: 5.0560e-04\n",
      "Epoch 99/100\n",
      "4/4 [==============================] - 0s 23ms/step - loss: 0.0052 - val_loss: 7.6491e-04\n",
      "Epoch 100/100\n",
      "4/4 [==============================] - 0s 23ms/step - loss: 0.0062 - val_loss: 5.0707e-04\n",
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      " Layer (type)                Output Shape              Param #   \n",
      "=================================================================\n",
      " simple_rnn (SimpleRNN)      (None, 5, 80)             6560      \n",
      "                                                                 \n",
      " dropout (Dropout)           (None, 5, 80)             0         \n",
      "                                                                 \n",
      " simple_rnn_1 (SimpleRNN)    (None, 100)               18100     \n",
      "                                                                 \n",
      " dropout_1 (Dropout)         (None, 100)               0         \n",
      "                                                                 \n",
      " dense (Dense)               (None, 1)                 101       \n",
      "                                                                 \n",
      "=================================================================\n",
      "Total params: 24,761\n",
      "Trainable params: 24,761\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    },
    {
     "data": {
      "image/png": "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+bkxptWHYWhqe4nIImPMsKbSH/dt8GA102gNXil1NCUkJBzw87Ywxs5x30QD1oVW7QevlFINRUWAdzsdepFVKaUaiYoA73GKNtEopQ5JaWlps59t2rSJffv2NfnZ7t27Aautva2KjgDv0jZ4pdTBKysrY/To0cyZM4errrqKm266iWuuuYYlS5YA8M9//pPFixdz7733UlNT02DeCy+8kBkzZnDHHXfUTWtLI0lClAR4t9OhQxUopQ5aUlISH3/8MVlZWTidTv785z9z6qmnUlBQwNixY3G5XDidTvr27ctzzz1HIBBoMO/FF19M37598fv9bW4kSdBeNEqpGPbNN9+wZ88exo8fD8Att9zCySefjNvtxuPx1KX7yU9+QklJCdnZ2XXdIpcvX87o0aMJBoNcdNFFJCQktKmRJCFKArzH5aBGe9EodXyb+TvIO/y7NxvoeDJc+HCzHw8cOJD777+ffv2se2icTift2rVrkGbjxo389re/5Z577uGrr77C4XDg9/sZP348H374YYN+8G1pJEmIlgDvdFATCB7rbCiljjM+n4+PPvoIl8uFMQa/31/3vlavXr249dZb8fv9vPTSSzz44IOccsopZGVlkZubW3fHaVsbSRKiJcC7HFT6NcArdVw7QE37SJo2bRrr1q3D5XJRUlKCz+erC/bhRITJkyezYMECHnvsMd544w0WL15cF+Db2kiSEDUXWUUvsiqlDlooFOKpp57iZz/7GT/+8Y/p27cvmzdvJjs7u8HzVwHy8vJ4++236/4fPnw4c+fOpbq6GrCeClX74A84uJEkn3zyScaNG1fXe6e1REmA14usSqmD9+KLLzJixAh8Ph8PPvggf/jDH/B6vTz//PP07duXNWvW4HQ6KS8v5/HHH2fTpk0sWbKE6667jm7durF06VJefPFFXn/99TY3kiRgddJvC69TTz3VHKrb3lhkznvsy0OeXyl1bKxateqYrr+6utrs27fPbNiwwUyfPr1u2pYtW8z3339v/vrXv5qqqirz7rvvmg0bNpivv/7arF+/vm7+9957z7jdbvP999+bvLw8k52dbT755BPz8ssvm3PPPdfMnTvXGGNMKBQyTz31lHnhhRdMYWGhuf32283GjRv3y08oFDIzZ840FRUVTea3qe0F5Jhm4mpUjCZ559s/8N2Wvcz/7fmtnCul1JF0PI8m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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,\n",
    "                                                 save_weights_only=True,\n",
    "                                                 save_best_only=True,\n",
    "                                                 monitor='val_loss')\n",
    "\n",
    "_model = model.fit(x_train, y_train, batch_size=batch_size, epochs=epochs, validation_data=(x_test, y_test), validation_freq=validation_freq,\n",
    "                    callbacks=[cp_callback])\n",
    "\n",
    "model.summary()\n",
    "\n",
    "file = open('./weights.txt', 'w')  # 参数提取\n",
    "for v in model.trainable_variables:\n",
    "    file.write(str(v.name) + '\\n')\n",
    "    file.write(str(v.shape) + '\\n')\n",
    "    file.write(str(v.numpy()) + '\\n')\n",
    "file.close()\n",
    "\n",
    "loss = _model.history['loss']\n",
    "val_loss = _model.history['val_loss']\n",
    "\n",
    "plt.plot(loss, label='训练损失')\n",
    "plt.plot(val_loss, label='测试损失')\n",
    "plt.title('训练和测试损失')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "c7582a6a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 预测\n",
    "# 测试集输入模型进行预测\n",
    "predicted_stock_price = model.predict(x_test)\n",
    "# 对预测数据还原---从（0，1）反归一化到原始范围\n",
    "predicted_stock_price = sc.inverse_transform(predicted_stock_price)\n",
    "# 对真实数据还原---从（0，1）反归一化到原始范围\n",
    "real_stock_price = sc.inverse_transform(test_set[seq_len:])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "a7060d5f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 画出真实数据和预测数据的对比曲线\n",
    "plt.plot(real_stock_price, color='red', label='股票价格')\n",
    "plt.plot(predicted_stock_price, color='blue', label='预测股票价格')\n",
    "plt.title('股票价格预测')\n",
    "plt.xlabel('时间')\n",
    "plt.ylabel('股票价格')\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "e7d6659a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "均方误差: 0.270810\n",
      "均方根误差: 0.520394\n",
      "平均绝对误差: 0.419214\n"
     ]
    }
   ],
   "source": [
    "# 评估\n",
    "# calculate MSE 均方误差 ---> E[(预测值-真实值)^2] (预测值减真实值求平方后求均值)\n",
    "mse = mean_squared_error(predicted_stock_price, real_stock_price)\n",
    "# calculate RMSE 均方根误差--->sqrt[MSE]    (对均方误差开方)\n",
    "rmse = math.sqrt(mean_squared_error(predicted_stock_price, real_stock_price))\n",
    "# calculate MAE 平均绝对误差----->E[|预测值-真实值|](预测值减真实值求绝对值后求均值）\n",
    "mae = mean_absolute_error(predicted_stock_price, real_stock_price)\n",
    "print('均方误差: %.6f' % mse)\n",
    "print('均方根误差: %.6f' % rmse)\n",
    "print('平均绝对误差: %.6f' % mae)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "254d8fb2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "准确率：[0.98406906]\n"
     ]
    }
   ],
   "source": [
    "#ACC\n",
    "error = 0\n",
    "summery = 0\n",
    "for i in range(24):\n",
    "    error += abs(predicted_stock_price[i] - real_stock_price[i])\n",
    "    summery += real_stock_price[i]\n",
    "acc = 1 - error/summery\n",
    "print(\"准确率：{}\".format(acc))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "deep",
   "language": "python",
   "name": "deep"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
